package com.modestmaps
{
	// This class is an extension to the modestmaps mapping API version 1.0 for Actionscript 3.
	// see http://www.modestmaps.com for details on the modestmaps API.
	// 4/24/08 Jay Wood  / San Diego Union-Tribune

	import com.modestmaps.extras.Overlay;
	import com.modestmaps.extras.PolylineOverlay;
	
	import mx.collections.ArrayCollection;
	import mx.collections.IList;
	
	/**
	 * Manages a set of Overlay instances for a given Map. 
	 * <p>
	 * Includes methods to add and remove an overlay from the map,
	 * show/hide all overlays, and show/hide overlays as a group, using a common
	 * groupID string to identify related overlays.
	 * </p>
	 * @see http:modestmaps.com the official ModestMaps site
	 * @see Map
	 * @see Overlay
	 * @see PolylineOverlay
	 */
	public class OverlayManager
	{
		// a list of the overlays for this map
		private var _overlays:IList;
		// a handle on the map
		private var _map:Map;

		/**
		 * Constructor -- creates a new OverlayManager and adds it to the map.
		 * @param map is the Map instance.
		 */
		public function OverlayManager(map:Map) 
		{
			_overlays = new ArrayCollection();
			_map = map;
		}
		
		/**
		 * Adds an overlay to the manager, adds it to the map, and
		 * sets its visibility property.
		 * @param overlay is the Overlay instance to be added.
		 */
		public function addOverlay(overlay:Overlay):void
		{
			overlay.visibility = true;
			_overlays.addItem(overlay);
            _map.addChildAt(overlay, _map.getChildIndex(_map.markerClip));

		}

		/**
		 * Removes the specified overlay from the manager and the map. 
		 * @param overlay is the Overlay instance to be removed.
		 */
		public function removeOverlay(overlay:Overlay):void
		{
			_overlays.removeItemAt(_overlays.getItemIndex(overlay));
			_map.removeChild(overlay);		
		}
		
		/**
		 * Remove all overlays matching the specified groupID.
		 * @param groupID identifies the overlays to be removed.
		 */
		public function removeGroup(groupID:String):void
		{
			for (var i:int=_overlays.length-1; i>=0; i--)
			{
				var overlay:Overlay = _overlays.getItemAt(i) as Overlay;
				if (overlay.groupID == groupID) removeOverlay(overlay);
			}
		}
			
		/**
		 * Return a list of the overlays being managed by this OverlayManager.
		 */
		public function get overlays():IList
		{
			return _overlays;
		}

		/** Hide all overlays */
		public function hideAll():void
		{
			setAllOverlaysVisible(false);
		}		
		
		/** Show all overlays */
		public function showAll():void 
		{
			setAllOverlaysVisible(true);
		}
		
		/** 
		 * Temporarily hides and then unhides overlays, e.g., during a zoom operation.
		 * @param hide specifies whether to hide or un-hide the overlays -- hide if <code>true</code>,
		 * un-hide if <code>false</code>.
		 */
		
		public function temporaryHide(hide:Boolean):void
		{
			for each (var overlay:Overlay in _overlays)
			{
				if (hide==true)
				{
					// set the visibility of the overlay to false, but leave 
					// the visibility property unchanged.
					overlay.visible = false;
				} else {
					// refresh the overlay's visibility (resets visible on the overlay
					// and its marker text according to stored visibility flag)
					overlay.visibility = overlay.visibility;
				}
			}
		}


		// helper function to show or hide all overlays -- 
		// param visibility indicates what to do: if true, show, if false, hide.
		private function setAllOverlaysVisible(visibility:Boolean):void
		{
			for each (var overlay:Overlay in _overlays) 
			{
				overlay.visibility = visibility;
			}
		}
			
		/** 
		 * Show all overlays matching the specified groupID.
		 * @param groupID identifies the overlays that will be shown.
		 */
		public function showGroup(groupID:String):void
		{
			setOverlayGroupVisible(groupID, true);
		}
		
		/** 
		 * Hide all overlays matching the specified groupID.
		 * @param groupID identifies the overlays that will be hidden.
		 */
		public function hideGroup(groupID:String):void
		{
			setOverlayGroupVisible(groupID, false);
		}
		
		// helper function sets the visibility of all overlays in the specified group. 
		private function setOverlayGroupVisible(groupID:String, visibility:Boolean):void
		{
			for each (var overlay:Overlay in _overlays)
			{
				if (overlay.groupID == groupID) overlay.visibility = visibility;
			}
		}
		
	}
}